package com.zretc.support.controller;

import com.alibaba.fastjson.JSONObject;
import com.zretc.support.entity.Online;
import com.zretc.support.entity.User;
import com.zretc.support.service.ChatSessionService;
import com.zretc.support.tool.AjaxResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint(value = "/chat/{id}")
public class WebsocketServiceEndpoint {

    Logger logger = LoggerFactory.getLogger(WebsocketServiceEndpoint.class);

    private static ChatSessionService chatSessionService;

    @Autowired
    public void setChatSessionService(ChatSessionService chatSessionService){
        WebsocketServiceEndpoint.chatSessionService = chatSessionService;
    }

    // 在线数
    private static long online = 0;
    // 存放当前Websocket对象
    private static CopyOnWriteArraySet<WebsocketServiceEndpoint> websocketServiceEndpoints = new CopyOnWriteArraySet<>();
    // 与客户端的会话Session
    private Session session;
    // 当前会话窗口Id
    private String fromId = "";

    /**
     * 成功连接
     * @param session
     * @param id
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("id") String id){
        this.session = session;
        // 将当前websocket对象存入到Set集合中
        websocketServiceEndpoints.add(this);
        //在线人数加1
        addOnlineCount();
        this.fromId = id;
        try {
            User user = chatSessionService.findById(fromId);
            // 群发消息
            Map<String,Object> map = new HashMap<>();
            map.put("msg","用户" + user.getUserName() + "已上线");
            sendMore(JSONObject.toJSONString(map));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void onClose(){
        // 移除当前websocket对象
        websocketServiceEndpoints.remove(this);
        // 在线人数 -1
        subOnLineCount();
    }

    /**
     * 收到客户端消息
     * @param message
     * @throws IOException
     */
    @OnMessage
    public void onMessage(String message) throws IOException {
        chatSessionService.pushMessage(fromId,null,message);
        sendMore(getData(null,message));
    }

    @OnError
    public void onError(Throwable e) {
        e.printStackTrace();
    }

    /**
     * 推送消息
     * @param message
     * @throws IOException
     */
    private void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    /**
     * 返回消息
     * @param toId
     * @param message
     * @return
     * @throws IOException
     */
    private String getData(String toId,String message) throws IOException{
        Online online = new Online();
        online.setOnlineMessage(message);
        online.setOnlineDate(new Date());
        online.setSender(chatSessionService.findById(fromId));
        online.setReceiver(chatSessionService.findById(toId));
        return JSONObject.toJSONString(new AjaxResponse(online));
    }

    /**
     * 群发消息
     * @param data
     */
    private void sendMore(String data){
        for (WebsocketServiceEndpoint w: websocketServiceEndpoints) {
            try{
                w.sendMessage(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 指定窗口推送消息
     * @param toId
     * @param online
     */
    public void sendTo(String toId,Online online){
        fromId = online.getSender().getUserTel();
        if (websocketServiceEndpoints.size() <= 1){
        }
        boolean flag = false;
        for (WebsocketServiceEndpoint e:websocketServiceEndpoints) {
            try{
                 if (e.fromId.equals(toId)){
                     flag = true;
                     e.sendMessage(getData(toId,online.getOnlineMessage()));
                     chatSessionService.pushMessage(fromId,toId,online.getOnlineMessage());
                 }
            } catch (IOException ex) {
                ex.printStackTrace();
                continue;
            }
        }
        if(!flag){
        }
    }


    private void subOnLineCount() {
        WebsocketServiceEndpoint.online--;
    }

    private synchronized long getOnlineCount() {
        return online;
    }

    private void addOnlineCount() {
        WebsocketServiceEndpoint.online++;
    }



}
